home *** CD-ROM | disk | FTP | other *** search
- /*
- ** TC_MENU.C
- **
- ** Turbo C version of James Pinson's Lattice C program PULLDOWN.C
- **
- ** I edited his program to suit my standard library (included) and
- ** to eliminate the warnings, also made adjustments for Turbo C.
- **
- ** Compile TC_ASM.C with tcc -c tc_asm
- **
- ** then use TC_MENU.PRJ to compile
- **
- **
- ** -- Rich S.
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <dos.h>
- #include <conio.h>
- #include <mem.h>
-
-
- #define NORMAL 7 /* change these as desired for color */
- #define HI_INTEN 15
- #define REVERSE 112
-
- #define TRUE 1
- #define FALSE 0
-
- unsigned int attribute;
- static char buff[4000];
-
- #define NU_MAIN 5 /* number of main menu options */
- #define NU_SUB 5 /* number of sub menu options */
-
- int menu();
- int pull_down();
- void make_inst();
- void demo();
- void help();
- void clear_window();
- void menubox();
- void make_window();
- int get_key();
-
-
- struct menu_str /* change this if you need more options */
- {
- char *head;
- char *body[NU_SUB];
- void (*fun1)();
- void (*fun2)();
- void (*fun3)();
- void (*fun4)();
- void (*fun5)();
- };
-
-
- /*-----------*/
- /* M A I N */
- /*-----------*/
-
- main()
- {
- extern unsigned int attribute;
-
- int hi_attr, nor_attr;
-
- static struct menu_str m_menu[NU_MAIN] =
- {
- " File ", /* The first menu option */
- " Dir ", /* Menu sub options */
- " Load ",
- " Save ",
- " Erase ",
- " Path ",
- demo, /* The functions each sub-option call */
- demo,
- demo, /* these all call the same fake function */
- demo,
- demo,
-
- " Locate ", /* The second menu option */
- " All-words ",
- " First-word ",
- "\0",
- "\0", /* space filler for unused option names */
- "\0",
- demo,
- demo,
- 0, /* unused function pointer */
- 0,
- 0,
-
- " Configure ", /* The third option */
- " Modem ",
- " Screen ",
- " Printer ",
- "\0",
- "\0",
- demo,
- demo,
- demo,
- 0,
- 0,
-
- " Output ", /* The fourth menu option */
- " Screen ",
- " Printer ",
- " Disk ",
- " Modem ",
- "\0",
- demo,
- demo,
- demo,
- demo,
- 0,
-
-
- " Help ", /* The fifth option */
- " Instant help (really works) ",
- "\0",
- "\0",
- "\0",
- "\0",
- help,
- 0,
- 0,
- 0,
- 0,
- };
-
-
- hi_attr = REVERSE;
- nor_attr = NORMAL;
-
- attribute = nor_attr;
- getscrn(buff);
- cls();
- cursor(0); /* hide cursor */
-
- make_inst(); /* Show instructions */
-
- menu(m_menu, NU_MAIN, NU_SUB, hi_attr, nor_attr);
-
- putscrn(buff); /* restore text display*/
- cursor(1); /* restore cursor */
- }
-
-
- /*-----------*/
- /* M E N U */
- /*-----------*/
-
- int menu(m_menu, nu_main, nu_sub, hi_attr, nor_attr)
- struct menu_str m_menu[];
- int nu_main, nu_sub, hi_attr, nor_attr;
- {
- extern unsigned int attribute;
-
- int i, j, cur_x, cur_y, cur_opt, found, expert = 1;
- char ch, ext,ltr;
-
- ch = ' ';
- ext = ' ';
- cur_opt = 0;
- found = 0;
-
- attribute = nor_attr;
-
- make_window(0, 0, 78, 1, 1);
-
- for (;;) /* endless loop */
- {
- for (i = 0; i < nu_main; i++)
- {
- j = 0;
- while (m_menu[i].head[j] != '\0')
- {
- ltr = m_menu[i].head[j];
- j++;
- if (ch == ltr && ch != ' ')
- {
- found = TRUE;
- cur_opt = i;
- }
- }
- }
- if (ch == 13)
- {
- found = TRUE;
- expert = FALSE;
- }
-
- ch = ' ';
- cur_x = 1;
- cur_y = 1;
-
- for (i = 0; i < nu_main; i++)
- {
- if (i == cur_opt)
- attribute = hi_attr;
- else
- attribute= nor_attr;
- fastwrite(cur_x, cur_y,attribute, m_menu[i].head);
- cur_x += strlen(m_menu[i].head) + 3;
- }
-
- if (!expert)
- found = TRUE;
-
- if (found)
- {
- ext = pull_down(m_menu, nu_sub, cur_opt); /* pull-down options */
- if (ext == 27)
- expert = TRUE;
- if (ext == 'r' || ext == 'l')
- expert = FALSE;
- if (ext == 'r')
- ++cur_opt;
- if (ext == 'l')
- --cur_opt;
- ch = ' ';
- ext = ' ';
- }
-
- if (!found)
- {
- ch = ' ';
- get_key(&ch, &ext);
- ch = toupper(ch);
- }
-
- if (ch == 27)
- return;
-
- if (ext == 'r' || ext == 'l')
- expert = 0;
- if (ext == 'r')
- ++cur_opt;
- if (ext == 'l')
- --cur_opt;
- if (cur_opt >= nu_main)
- cur_opt = 0;
- if (cur_opt < 0)
- cur_opt = nu_main - 1;
- ext = ' ';
- found = 0;
-
- } /* end for (;;) */
- }
-
-
-
- /*---------------------*/
- /* P U L L _ D O W N */
- /*---------------------*/
-
- int pull_down(m_menu, nu_sub, position)
- struct menu_str m_menu[];
- int position;
- {
- extern unsigned int attribute;
- char ch = ' ', ltr;
- int ext = ' ', hi_attr, nor_attr;
- int i, j, tx, ty, start, width, nu_opt, cur_opt = 0, found = FALSE;
-
- nu_opt = nu_sub;
-
- /* nu_sub = number of possible pull-down options */
- /* find out how many are in use */
-
- for (i = 0; i < nu_opt; i++)
- {
- if (m_menu[position].body[i][0] == '\0')
- {
- nu_opt = i;
- break;
- }
- }
-
- hi_attr = REVERSE;
- nor_attr = NORMAL;
-
- attribute = nor_attr;
-
- start = 1; /* Figure where to draw pull-down box */
- /* 1 is column to start 1st box */
- /* Add up length of menu heads */
-
- for (i = 0; i < position; i++)
- start += strlen(m_menu[i].head) + 3;
-
- width = 0; /* figure max length of window */
-
- for (i = 0; i < nu_opt; i++)
- if (strlen(m_menu[position].body[i]) > width)
- width = strlen(m_menu[position].body[i]);
-
- /* move box to left if it will spill off right side */
-
- if (start + width + 1 > 79)
- start = 79 - width - 2;
-
- getscrn(buff);
-
- make_window(start++, 2, width, nu_opt, 0); /*make a window */
- attribute = nor_attr;
-
- tx = start; /* reposition for writing */
- ty = 3;
-
- for (;;)
- {
- for (i = 0; i < nu_opt; i++)
- {
- if (i == cur_opt)
- attribute = hi_attr;
- else
- attribute = nor_attr;
- fastwrite(tx, ty++,attribute, m_menu[position].body[i]);
- }
-
- attribute = nor_attr;
-
- if (found)
- {
- putscrn(buff); /* remove box */
-
- /* If you want more than 5 menu options */
- /* change this next switch statement */
-
- switch(cur_opt) /* call function */
- {
- case 0: (*m_menu[position].fun1)(); break;
- case 1: (*m_menu[position].fun2)(); break;
- case 2: (*m_menu[position].fun3)(); break;
- case 3: (*m_menu[position].fun4)(); break;
- case 4: (*m_menu[position].fun5)(); break;
- }
-
- /* found = FALSE; */
- if (kbhit())
- getch(); /* make sure keyboard buffer is clear */
- return(' ');
- }
-
- tx = start;
- ty = 3;
- get_key(&ch, &ext); /* get a character */
- ch = toupper(ch);
- if (ext == 'd')
- ++cur_opt;
- if (ext == 'u')
- --cur_opt;
- if (cur_opt >= nu_opt)
- cur_opt = 0;
- if (cur_opt < 0)
- cur_opt = nu_opt - 1;
-
- if (ch == 13)
- found = TRUE;
-
- for (i = 0; i < nu_opt; i++) /* does it match an option? */
- {
- j = 0;
- while (m_menu[position].body[i][j] != '\0')
- {
- ltr = m_menu[position].body[i][j];
- j++;
- if (ch == ltr)
- {
- cur_opt = i;
- found = TRUE;
- }
- }
- }
-
- if (ext == 'l'|| ext == 'r')
- break;
-
- if (ch == 27) /* EXIT IF ESCAPE KEY */
- {
- ext = ch;
- break;
- }
-
- ext = ' ';
- ch = ' ';
-
- } /* end for (;;) */
-
- putscrn(buff);
- return (ext);
- }
- /*---------------------*/
- /* M A K E _ I N S T */
- /*---------------------*/
-
- void make_inst()
- {
- extern unsigned int attribute;
-
- attribute = NORMAL;
-
- fastwrite( 1, 4,attribute, "INSTRUCTIONS:");
- fastwrite( 1, 6,attribute, "EXPERT MODE: Select by touching the key which represents each option.");
- fastwrite(15, 7,attribute, "(the capital letter)");
-
- fastwrite( 1, 10,attribute, "ASSIST MODE: Pull-down menu by touching 'enter' or a cursor key.");
- fastwrite(14, 11,attribute, "Select by highlighting with cursor keys- then touch return");
- fastwrite(14, 13,attribute, "Return to Expert mode by touching 'escape'");
-
- fastwrite( 1, 15,attribute, "EXIT: Touch 'Escape' while in expert mode.");
- }
-
-
- /*-----------*/
- /* D E M O */
- /*-----------*/
-
- void demo()
- {
- getscrn(buff);
- make_window(19, 9, 40, 5, 1);
-
- fastwrite(21, 11,HI_INTEN, "Put your favorite routine here ");
- fastwrite(21, 14,HI_INTEN, "touch any key to return to menu");
- getch();
-
- putscrn(buff);
- }
-
-
- /*-----------*/
- /* H E L P */
- /*-----------*/
-
- void help()
- {
- attribute = NORMAL;
- getscrn(buff);
-
- clear_window(0, 3, 80, 21);
- fastwrite(1, 7,HI_INTEN, "This is a demonstration of a help screen.");
- fastwrite(1, 9,HI_INTEN, "This text was written by means of direct memory address.");
- fastwrite(1, 10,HI_INTEN, "The original screen has been saved and will be restored ");
- fastwrite(1, 11,HI_INTEN, "when you exit this 'help' screen.");
- fastwrite(1, 14,HI_INTEN, "Please touch any key to continue.");
-
- getch();
- putscrn(buff);
- }
-
-
- /* Screen Function Library */
-
- /*---------------------*/
- /* S E T _ C O L O R */
- /*---------------------*/
-
- /* Call with foreground and background colors. Returns attribute. */
-
- int set_color(foreground, background)
- int foreground,background;
- {
- return (background << 4 | foreground);
- }
-
-
-
- /*---------------------------*/
- /* C L E A R _ W I N D O W */
- /*---------------------------*/
-
- void clear_window(x, y, width, height) /* Call with x,y of upper left */
- unsigned int x, y, width, height; /* corner of window area. */
- { /* Clears down and to right */
- extern unsigned int attribute; /* Cleared with active attribute */
- union REGS regist; /* Use on displayed page only! */
-
- regist.x.ax = 0x0600;
- regist.h.ch = y;
- regist.h.cl = x;
- regist.x.dx = (y + height - 1) << 8 | x + width - 1;
- regist.h.bh = attribute;
- int86(0x10, ®ist, ®ist);
- }
-
-
- /*---------*/
- /* B O X */
- /*---------*/
-
- void menubox(x, y, width, height, type) /* type 0 = pull-down box */
- int x, y, width, height, type; /* type 1 = regular box */
- {
- extern unsigned int attribute;
- int i, u_right, u_left;
- char string[82];
-
- if (type == 0) /* following sets corners */
- {
- u_left = 194;
- u_right = 194;
- }
- else if (type == 1)
- {
- u_left = 218;
- u_right = 191;
- }
-
- string[0] = u_left;
- for (i = 1; i <= width; string[i++] = 196);
- string[i++] = u_right;
- string[i] = '\0';
- fastwrite(x, y++,attribute, string);
-
- for (i = 0; i < height; i++)
- {
- fastwrite(x, y,attribute, "\xB3");
- fastwrite(x + width + 1, y++,attribute, "\xB3");
- }
-
- string[0]=192;
- for(i = 1; i <= width; string[i++] = 196);
- string[i++] = 217;
- string[i] = '\0';
- fastwrite(x, y++,attribute, string);
- }
-
- /*-------------------------*/
- /* M A K E _ W I N D O W */
- /*-------------------------*/
-
- void make_window(x, y, width, height, type) /* Draws and clears a box */
- unsigned int x, y, width, height, type;
- {
- menubox(x++, y++, width, height, type); /* Draw box */
- clear_window(x, y, width, height); /* Clear interior */
- }
-
- /*-----------------*/
- /* G E T _ K E Y */
- /*-----------------*/
-
- int get_key(ch, ext) /* Read a char */
- char *ch; /* Return character in ch */
- int *ext; /* If it is a function key */
- { /* return following in ext */
- *ch = getch(); /* up-arrow = 'u' */
- if (!*ch) /* down-arrow = 'd' */
- { /* right-arrow = 'r' */
- *ext = getch(); /* left-arrow = 'l' */
- switch (*ext)
- {
- case 'H': *ext = 'u'; break; /* up */
- case 'P': *ext = 'd'; break; /* down */
- case 'M': *ext = 'r'; break; /* right */
- case 'K': *ext = 'l'; break; /* left */
- case 'G': *ext = 'h'; break; /* home */
- case 'O': *ext = 'e'; break; /* end */
- case 'R': *ext = 'I'; break; /* insert */
- case 'S': *ext = 'D'; break; /* delete */
- }
- }
- }
-
-